/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "ohos_init.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cmsis_os2.h"
#include "iot_uart.h"
#include "uart.h"
#include "iot_errno.h"
#include "los_sem.h"
#include "pinctrl.h"


#define AT_RX_BUFFER_SIZE 64
static uint8_t g_atSdkRxBuff[AT_RX_BUFFER_SIZE] = { 0 };

typedef void (*HalSdkRxCallback)(const void *buffer, uint16_t length, bool error);

// id: 表示串口号, 0: UART0, 1: UART1, 2: UART2
uint32_t HalSdkUartInit(uint8_t id, const IotUartAttribute *param, HalSdkRxCallback callback)
{
    if (param == NULL) {
        return IOT_FAILURE;
    }
    if(id < UART_BUS_0 || id > UART_BUS_MAX_NUM) {
        return IOT_FAILURE;
    }
    if(param->txBlock | param->pad) {
    }
    uart_buffer_config_t uart_buffer_config;
    uart_pin_config_t uart_pin_config = {
        .tx_pin = 0,
        .rx_pin = 0,
        .cts_pin = PIN_NONE,
        .rts_pin = PIN_NONE,
    };
    if(param->baudRate <= 0 || param->dataBits < IOT_UART_DATA_BIT_5 || param->dataBits > IOT_UART_DATA_BIT_8 || 
        param->stopBits < IOT_UART_STOP_BIT_1 || param->stopBits > IOT_UART_STOP_BIT_2 || 
        param->parity < IOT_UART_PARITY_NONE
        || param->parity > IOT_UART_PARITY_EVEN) {
        return IOT_FAILURE;
    }

    uart_attr_t uart_line_config;
    uart_line_config.baud_rate = param->baudRate;
    if(param->baudRate >= 3000000)
    {
        uart_line_config.baud_rate = 3000000;
    }
    uart_line_config.data_bits = param->dataBits - IOT_UART_DATA_BIT_5;
    uart_line_config.stop_bits = param->stopBits - IOT_UART_STOP_BIT_1;
    uart_line_config.parity = param->parity;
    uapi_uart_deinit(id);
    uart_buffer_config.rx_buffer_size = AT_RX_BUFFER_SIZE;
    uart_buffer_config.rx_buffer = g_atSdkRxBuff;
#if defined(CONFIG_UART_SUPPORT_DMA)
    uart_extra_attr_t extra_attr = {
        .tx_dma_enable = UART_DMA_TX_ENABLE,
        .tx_int_threshold = 0,
        .rx_dma_enable = UART_DMA_RX_ENABLE,
        .rx_int_threshold = 0
    };
    uapi_dma_init();
    uapi_dma_open();
    if (uapi_uart_init((uart_bus_t)id, &uart_pin_config, &uart_line_config, &extra_attr, &uart_buffer_config) != ERRCODE_SUCC) {
        return IOT_FAILURE;
    }
#else
    if (uapi_uart_init((uart_bus_t)id, &uart_pin_config, &uart_line_config, NULL, &uart_buffer_config) != ERRCODE_SUCC) {
        return IOT_FAILURE;
    }
#endif
    if(param->rxBlock == IOT_UART_BLOCK_STATE_BLOCK) {
        (void)uapi_uart_register_rx_callback(id, UART_RX_CONDITION_FULL_OR_SUFFICIENT_DATA_OR_IDLE, AT_RX_BUFFER_SIZE, callback);
    }
    return IOT_SUCCESS;
}

void HalSdkUartWrite(uint8_t id, const uint8_t *data, uint16_t length)
{
    uapi_uart_write((uart_bus_t)id, (const uint8_t *)data, strlen(data), 0);
}

